package com.feature50.makeover.whackachet;

import com.feature50.makeover.AppPanel;
import com.feature50.makeover.utils.ImageUtils;
import com.feature50.makeover.wii.DartListener;
import com.feature50.makeover.wii.WiiDartTracker;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.timing.TimingTargetAdapter;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

public class ChetPanel extends AppPanel {
    private Chet[] chet = new Chet[4];
    private BufferedImage background;
    private Animator showChetAnimator;
    private Animator hideChetAnimator;
    private WiiDartTracker tracker;

    private BufferedImage hammerUp;
    private BufferedImage hammerDown;

    private BufferedImage hammer;

    public ChetPanel() {
        init();
    }

    private void init() {
        tracker = new WiiDartTracker();
        tracker.activeWiimote();

        tracker.addDartListener(new DartListener() {
            public void dartFired(float velocity, float x, float y) {
                hammer = hammerDown;
                repaint();

                boolean hit = checkCollision();

                new Thread() {
                    @Override
                    public void run() {
                        while (true) {
                            try {
                                Thread.sleep(50);
                                if (!tracker.isFired()) {
                                    hammer = hammerUp;
                                    repaint();
                                    return;
                                }
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }.start();
            }
        });

        background = ImageUtils.getImage("whackachet.png");
        hammerUp = ImageUtils.getImage("hammerup.png");
        hammerDown = ImageUtils.getImage("hammerdown.png");

        hammer = hammerUp;

        for (int i = 0; i < chet.length; i++) {
            chet[i] = new Chet();
            add(chet[i]);
        }

        setOpaque(false);
        setBackground(Color.WHITE);
    }

    private boolean checkCollision() {
        float dx = tracker.getDartX();
        float dy = tracker.getDartY();

        int cx = (int) (getWidth() * dx);
        int cy = (int) (getHeight() * dy);

        cx -= (hammer.getWidth() / 2);
        cy -= (hammer.getHeight() / 2);

        cx += 29;
        cy += 150;

        for (int i = 0; i < chet.length; i++) {
            if (chet[i].isChetShowing()) {
                if (chet[i].isHit(cx, cy, cx + 60, cy + 30)) {
                    chet[i].setHit(true);
                    return true;
                }
            }
        }

        return false;
    }

    @Override
    protected void paintComponent(Graphics g) {
        int x = 0;
        int y = getHeight() - background.getHeight();
        g.drawImage(background, x, y, null);
    }

    @Override
    protected void paintChildren(Graphics g) {
        super.paintChildren(g);

        float dx = tracker.getDartX();
        float dy = tracker.getDartY();

        int cx = (int) (getWidth() * dx);
        int cy = (int) (getHeight() * dy);

        cx -= (hammer.getWidth() / 2);
        cy -= (hammer.getHeight() / 2);

        g.drawImage(hammer, cx, cy, null);

    }

    @Override
    public void doLayout() {
        int h = getHeight();
        int ch = chet[0].getPreferredSize().height;

        Dimension s = chet[0].getPreferredSize();
        chet[0].setBounds(185, h - ch - 40, s.width, s.height);
        chet[1].setBounds(385, h - ch - 40, s.width, s.height);
        chet[2].setBounds(575, h - ch - 40, s.width, s.height);
        chet[3].setBounds(770, h - ch - 40, s.width, s.height);
    }

    @Override
    public void panelDisplayed() {
        new ShowThread().start();
        new Thread() {
            @Override
            public void run() {
                while (true) {
                    repaint();

                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {}
                }
            }
        }.start();

    }

    private void showChet(final Chet chet, int duration) {
        chet.setChetShowing(true);

        showChetAnimator = new Animator(duration, new TimingTargetAdapter() {
            @Override
            public void timingEvent(float fraction) {
                chet.setBuilt(fraction);
                chet.repaint();
            }
        });
        showChetAnimator.setDeceleration(0.8f);
        showChetAnimator.start();
    }

    private void hideChet(final Chet chet) {
        if (!chet.isChetShowing()) return;
        chet.setChetShowing(false);

        hideChetAnimator = new Animator(250, new TimingTargetAdapter() {
            @Override
            public void timingEvent(float fraction) {
                chet.setBuilt(fraction);
                chet.repaint();
            }
        });
        hideChetAnimator.setAcceleration(0.8f);
        hideChetAnimator.setStartFraction(1.0f);
        hideChetAnimator.setStartDirection(Animator.Direction.BACKWARD);
        hideChetAnimator.start();
    }

    private class WiiThread extends Thread {
        
    }

    private class ShowThread extends Thread {
        private Random random = new Random();

        @Override
        public void run() {
            while (true) {
                try {
                    // how long to wait until showing the next chet
                    int sleep = random.nextInt(5000);
                    Thread.sleep(sleep);

                    // choose a random chet to show
                    int chetIndex = random.nextInt(4);
                    Chet ch = chet[chetIndex];

                    // show the chet at a random rate of speed
                    int speed = 250 + random.nextInt(1000);
                    showChet(ch, speed);

                    // wait for a random amount of time before hiding chet, plus the rate of speed to show chet
                    int wait = speed + random.nextInt(2000);
                    Thread.sleep(wait);

                    // hide chet if not already hidden
                    hideChet(ch);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
